﻿using System;
using System.ComponentModel;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using System.Collections.Generic;
using System.Windows.Controls;

namespace DotNet.Phone8.MvvmLight.Extensions
{
    //public delegate void NavigatedViewModelEventHandler(Type t);

    public class NavigateService : INavigateService
    {
        /// <summary>
        /// View和ViewModel的配对关系
        /// </summary>
        private Dictionary<Type, Type> dicViewViewModel;
        //private List<MethodInfo> navigatedMethods;

        private PhoneApplicationFrame frame;

        public PhoneApplicationFrame RootFrame
        {
            get { return frame; }
        }

        /// <summary>
        /// 是否从墓碑中恢复
        /// </summary>
        public bool RecoveredFromTombstoning { get; set; }

        /// <summary>
        /// 导航到页面时发生
        /// </summary>
        public event NavigatedEventHandler Navigated;

        /// <summary>
        /// 当请求新的导航时发生
        /// </summary>
        public event NavigatingCancelEventHandler Navigating;

        /// <summary>
        /// 按回退键时发生
        /// </summary>
        public event EventHandler<CancelEventArgs> BackKeyPress;

        public NavigateService(PhoneApplicationFrame rootFrame)
        {
            dicViewViewModel = new Dictionary<Type, Type>();
            //navigatedMethods = new Dictionary<Type, MethodInfo>();

            frame = rootFrame;
            this.frame.Navigated += frame_Navigated;
            this.frame.Navigating += frame_Navigating;
            this.frame.BackKeyPress += frame_BackKeyPress;
        }

        private void frame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            if (this.Navigated != null)
            {
                this.Navigated.Invoke(sender, e);
            }

            if (e.Uri.ToString() == "app://external/")
            {
                RecoveredFromTombstoning = true;
            }
            else
            {
                RecoveredFromTombstoning = false;
            }

            //清空导航参数
            navigaionUri = null;
        }

        private void frame_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
        {
            if (this.Navigating != null)
            {
                Navigating(sender, e);
            }
        }

        private void frame_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (BackKeyPress != null)
            {
                BackKeyPress(sender, e);
            }
        }

        public bool Navigate(NavigationUri source)
        {
            Uri uri = source as Uri;
            navigaionUri = source;

            return this.frame.Navigate(uri);
        }

        /// <summary>
        /// 导航
        /// </summary>
        /// <param name="desUri">导航目标页</param>
        /// <returns>是否成功</returns>
        public bool Navigate(string desUri, UriKind uriKind)
        {
            return this.frame.Navigate(new Uri(desUri, uriKind));
        }

        private NavigationUri navigaionUri;

        public NavigationUri NavigationUri
        {
            get { return navigaionUri; }
        }

        public void Register<TView, TViewModel>()
            where TView : class
            where TViewModel : class
        {
            Type tView = typeof(TView);
            Type tViewModel = typeof(TViewModel);

            if (!dicViewViewModel.ContainsKey(tViewModel))
            {
                dicViewViewModel.Add(tViewModel, tView);
            }
        }

        public Type GetViewType<TViewModel>() where TViewModel : class
        {
            Type tViewModel = typeof(TViewModel);
            if (dicViewViewModel.ContainsKey(tViewModel))
            {
                return dicViewViewModel[tViewModel];
            }
            else
            {
                return typeof(object);
            }
        }

        public Type GetViewType(Type tViewModel)
        {
            if (dicViewViewModel.ContainsKey(tViewModel))
            {
                return dicViewViewModel[tViewModel];
            }
            else
            {
                return typeof(object);
            }
        }

        public void RemoveBackEntry()
        {
            if (frame != null && frame.Content != null && frame.Content is Page)
            {
                Page page = frame.Content as Page;

                page.NavigationService.RemoveBackEntry();
            }
        }
    }
}
